<script>
import { mapState, mapActions } from 'pinia'
import { useShopStore } from '../stores/05.actions(选项式)'

export default {
  data() {
    return {
      // 登录表单
      loginForm: {
        username: '',
        password: ''
      },
      // 登录状态消息
      loginMessage: '',
      // 添加到购物车的商品ID
      selectedProductId: 1,
      // 添加到购物车的数量
      quantity: 1,
      // 操作结果消息
      actionMessage: '',
      // 是否显示结果消息
      showMessage: false,
      // 消息类型（成功/失败）
      messageType: 'success'
    }
  },
  computed: {
    // 获取store实例
    shopStore() {
      return useShopStore()
    },
    
    // 映射store中的状态
    ...mapState(useShopStore, [
      'products',
      'cart',
      'user',
      'orderHistory'
    ]),
    
    // 映射store中的getters
    ...mapState(useShopStore, [
      'cartItemCount',
      'cartTotalPrice',
      'isAuthenticated'
    ])
  },
  methods: {
    // 映射store中的actions
    ...mapActions(useShopStore, [
      'clearCart',
      'logout',
      'checkout'
    ]),
    
    // 处理登录
    async handleLogin() {
      if (!this.loginForm.username || !this.loginForm.password) {
        this.showActionMessage('用户名和密码不能为空', 'error')
        return
      }
      
      try {
        const result = await this.shopStore.login(this.loginForm.username, this.loginForm.password)
        this.showActionMessage(result.message, result.success ? 'success' : 'error')
        
        if (result.success) {
          this.loginForm = { username: '', password: '' }
        }
      } catch (error) {
        this.showActionMessage(error.message, 'error')
      }
    },
    
    // 处理登出
    handleLogout() {
      const result = this.logout()
      this.showActionMessage(result.message, 'success')
    },
    
    // 添加商品到购物车
    addProductToCart() {
      try {
        const result = this.shopStore.addToCart(Number(this.selectedProductId), Number(this.quantity))
        this.showActionMessage(result.message, 'success')
      } catch (error) {
        this.showActionMessage(error.message, 'error')
      }
    },
    
    // 从购物车移除商品
    removeProductFromCart(productId) {
      try {
        const result = this.shopStore.removeFromCart(productId)
        this.showActionMessage(result.message, 'success')
      } catch (error) {
        this.showActionMessage(error.message, 'error')
      }
    },
    
    // 处理结账
    async handleCheckout() {
      try {
        const result = await this.checkout()
        this.showActionMessage(result.message, result.success ? 'success' : 'error')
      } catch (error) {
        this.showActionMessage(error.message, 'error')
      }
    },
    
    // 显示操作结果消息
    showActionMessage(message, type = 'success') {
      this.actionMessage = message
      this.messageType = type
      this.showMessage = true
      
      // 3秒后自动隐藏消息
      setTimeout(() => {
        this.showMessage = false
      }, 3000)
    }
  }
}
</script>

<template>
  <div class="tutorial-container">
    <header>
      <h1>05.actions(选项式)</h1>
      <p class="subtitle">学习如何在选项式API中定义和使用actions</p>
      
      <nav class="tutorial-nav">
        <router-link to="/01" class="nav-link">01.认识pinia</router-link>
        <router-link to="/02" class="nav-link">02.定义store(选项式)</router-link>
        <router-link to="/03" class="nav-link">03.state(选项式)</router-link>
        <router-link to="/04" class="nav-link">04.getters(选项式)</router-link>
        <router-link to="/05" class="nav-link">05.actions(选项式)</router-link>
      </nav>
    </header>

    <main>
      <section class="intro">
        <h2>什么是 Actions?</h2>
        <p>Actions 相当于组件中的 methods。它们可以包含任意异步或同步操作，可以调用其他 actions，可以通过 this 访问整个 store 实例。</p>
        
        <div class="code-example">
          <pre><code>// 定义一个带有actions的store
export const useStore = defineStore('storeId', {
  state: () => ({
    count: 0,
    userData: null
  }),
  actions: {
    // 同步action
    increment() {
      this.count++
    },
    // 异步action
    async fetchUserData() {
      const response = await fetch('/api/user')
      this.userData = await response.json()
    },
    // 调用其他action的action
    async initUser() {
      await this.fetchUserData()
      this.increment()
    }
  }
})</code></pre>
        </div>
      </section>

      <div class="demo-section">
        <div class="shop-demo">
          <h2>购物系统示例</h2>
          
          <!-- 操作结果消息 -->
          <div v-if="showMessage" :class="['message', messageType]">
            {{ actionMessage }}
          </div>
          
          <!-- 用户登录部分 -->
          <div class="card">
            <h3>用户管理</h3>
            
            <div v-if="!isAuthenticated" class="login-form">
              <div class="form-group">
                <label>用户名</label>
                <input v-model="loginForm.username" type="text" placeholder="请输入用户名" />
              </div>
              
              <div class="form-group">
                <label>密码</label>
                <input v-model="loginForm.password" type="password" placeholder="请输入密码" />
              </div>
              
              <button @click="handleLogin" class="btn primary">登录</button>
            </div>
            
            <div v-else class="user-info">
              <h4>欢迎回来，{{ user.name }}</h4>
              <p>积分: {{ user.points }}</p>
              <button @click="handleLogout" class="btn secondary">登出</button>
            </div>
          </div>
          
          <!-- 商品列表 -->
          <div class="card">
            <h3>商品列表</h3>
            
            <div class="products-list">
              <div v-for="product in products" :key="product.id" class="product-item">
                <div class="product-info">
                  <h4>{{ product.name }}</h4>
                  <p>价格: ¥{{ product.price }}</p>
                  <p>库存: {{ product.inventory }}</p>
                </div>
                
                <div class="product-actions" v-if="product.inventory > 0">
                  <button 
                    @click="() => { selectedProductId = product.id; quantity = 1; addProductToCart(); }" 
                    class="btn primary small"
                  >
                    加入购物车
                  </button>
                </div>
                <div v-else class="product-actions">
                  <span class="out-of-stock">已售罄</span>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 购物车 -->
          <div class="card">
            <h3>购物车 ({{ cartItemCount }})</h3>
            
            <div v-if="cart.length === 0" class="empty-cart">
              <p>购物车为空</p>
            </div>
            
            <div v-else>
              <div class="cart-items">
                <div v-for="item in cart" :key="item.productId" class="cart-item">
                  <div class="item-info">
                    <h4>{{ products.find(p => p.id === item.productId)?.name }}</h4>
                    <p>数量: {{ item.quantity }}</p>
                    <p>单价: ¥{{ products.find(p => p.id === item.productId)?.price }}</p>
                    <p>小计: ¥{{ (products.find(p => p.id === item.productId)?.price || 0) * item.quantity }}</p>
                  </div>
                  
                  <div class="item-actions">
                    <button @click="() => removeProductFromCart(item.productId)" class="btn danger small">移除</button>
                  </div>
                </div>
              </div>
              
              <div class="cart-summary">
                <p class="total">总计: ¥{{ cartTotalPrice }}</p>
                <div class="cart-actions">
                  <button @click="clearCart" class="btn secondary">清空购物车</button>
                  <button @click="handleCheckout" class="btn primary" :disabled="!isAuthenticated">
                    {{ isAuthenticated ? '结账' : '请先登录' }}
                  </button>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 订单历史 -->
          <div v-if="isAuthenticated && orderHistory.length > 0" class="card">
            <h3>订单历史</h3>
            
            <div class="order-history">
              <div v-for="order in orderHistory" :key="order.id" class="order-item">
                <div class="order-header">
                  <h4>订单 #{{ order.id }}</h4>
                  <p>日期: {{ new Date(order.date).toLocaleString() }}</p>
                  <p>状态: {{ order.status }}</p>
                </div>
                
                <div class="order-details">
                  <p>总金额: ¥{{ order.totalAmount }}</p>
                  <p>商品数量: {{ order.items.reduce((sum, item) => sum + item.quantity, 0) }}</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <section class="explanation">
        <h2>选项式API中使用Actions</h2>
        
        <div class="subsection">
          <h3>1. 直接访问store实例</h3>
          <p>在组件中，你可以通过store实例直接调用actions：</p>
          <div class="code-example">
            <pre><code>// 在组件中
export default {
  setup() {
    const store = useStore()
    return { store }
  },
  methods: {
    someMethod() {
      // 直接调用action
      this.store.increment()
      
      // 调用异步action
      this.store.fetchUserData()
    }
  }
}</code></pre>
          </div>
        </div>
        
        <div class="subsection">
          <h3>2. 使用mapActions辅助函数</h3>
          <p>你可以使用mapActions辅助函数将store中的actions映射到组件的methods中：</p>
          <div class="code-example">
            <pre><code>import { mapActions } from 'pinia'
import { useStore } from './store'

export default {
  methods: {
    // 将actions映射为组件的方法
    ...mapActions(useStore, ['increment', 'fetchUserData']),
    
    // 使用自定义名称映射
    ...mapActions(useStore, {
      add: 'increment',
      fetch: 'fetchUserData'
    })
  }
}</code></pre>
          </div>
        </div>
        
        <div class="subsection">
          <h3>3. Actions的特点</h3>
          <ul>
            <li>Actions可以是异步的，支持async/await语法</li>
            <li>可以通过this访问store的state、getters和其他actions</li>
            <li>可以接收任意参数并返回任何值</li>
            <li>可以在actions中修改state</li>
            <li>可以在actions中调用其他actions</li>
          </ul>
        </div>
      </section>
    </main>
  </div>
</template>

<style scoped>
.tutorial-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

header {
  margin-bottom: 30px;
  border-bottom: 1px solid #eee;
  padding-bottom: 20px;
}

h1 {
  font-size: 2.5rem;
  margin-bottom: 10px;
}

.subtitle {
  font-size: 1.2rem;
  color: #666;
  margin-bottom: 20px;
}

.tutorial-nav {
  display: flex;
  gap: 15px;
  margin-top: 20px;
}

.nav-link {
  padding: 8px 15px;
  background-color: #f5f5f5;
  border-radius: 4px;
  text-decoration: none;
  color: #333;
  transition: background-color 0.2s;
}

.nav-link:hover {
  background-color: #e0e0e0;
}

.intro {
  margin-bottom: 40px;
}

.code-example {
  background-color: #f8f8f8;
  border-radius: 6px;
  padding: 15px;
  margin: 15px 0;
  overflow-x: auto;
}

pre {
  margin: 0;
}

code {
  font-family: 'Courier New', monospace;
  font-size: 0.9rem;
}

.demo-section {
  margin-bottom: 40px;
}

.card {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  padding: 20px;
  margin-bottom: 20px;
}

.form-group {
  margin-bottom: 15px;
}

label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
}

input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 1rem;
}

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  transition: background-color 0.2s;
}

.btn.primary {
  background-color: #4CAF50;
  color: white;
}

.btn.primary:hover {
  background-color: #3e8e41;
}

.btn.secondary {
  background-color: #f1f1f1;
  color: #333;
}

.btn.secondary:hover {
  background-color: #e0e0e0;
}

.btn.danger {
  background-color: #f44336;
  color: white;
}

.btn.danger:hover {
  background-color: #d32f2f;
}

.btn.small {
  padding: 4px 8px;
  font-size: 0.9rem;
}

.btn:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.message {
  padding: 10px 15px;
  border-radius: 4px;
  margin-bottom: 20px;
}

.message.success {
  background-color: #dff0d8;
  color: #3c763d;
  border: 1px solid #d6e9c6;
}

.message.error {
  background-color: #f2dede;
  color: #a94442;
  border: 1px solid #ebccd1;
}

.products-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 20px;
}

.product-item {
  border: 1px solid #eee;
  border-radius: 6px;
  padding: 15px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.product-info {
  margin-bottom: 15px;
}

.product-actions {
  display: flex;
  justify-content: flex-end;
}

.out-of-stock {
  color: #f44336;
  font-style: italic;
}

.cart-items {
  margin-bottom: 20px;
}

.cart-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid #eee;
}

.cart-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 20px;
}

.total {
  font-size: 1.2rem;
  font-weight: bold;
}

.cart-actions {
  display: flex;
  gap: 10px;
}

.empty-cart {
  text-align: center;
  padding: 20px;
  color: #666;
}

.order-history {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.order-item {
  border: 1px solid #eee;
  border-radius: 6px;
  padding: 15px;
}

.order-header {
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.explanation {
  margin-top: 40px;
}

.subsection {
  margin-bottom: 30px;
}

ul {
  padding-left: 20px;
}

li {
  margin-bottom: 8px;
}
</style>
